﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Xml;

namespace T.FAS.Runtime.DataAccess.SQLDom
{
    /// <summary>
    /// 子查询SQL语句类
    /// </summary>
    /// <remarks>为了支持一个数据对象包含多个数据库表的场景，使用子查询统一处理</remarks>
    public class SubQuerySqlStatement : SqlTable
    {
        #region 常量      

        #endregion

        #region 字段

        /// <summary>
        /// Select语句中的核心查询主体
        /// </summary>
        private FromItem mainFromItem;

        /// <summary>
        /// 返回获取数据的前多少条，默认值-1
        /// </summary>
        private int topSize = -1;

        #endregion

        #region 构造函数

        /// <summary>
        /// 构造函数
        /// </summary>
        public SubQuerySqlStatement()
            : base()
        {           
            From = new From();
            mainFromItem = new FromItem();
            From.ChildCollection.Add(mainFromItem);
            SelectList = new SelectFieldListStatement();
            JoinCondition = new JoinConditionStatement();
            FilterCondition = new ConditionStatement();
            OrderByCondition = new ConditionStatement();
            DictFieldAliasMapping = new Dictionary<string, string>();
        }

        #endregion

        #region 属性

        /// <summary>
        /// 查询字段列表
        /// </summary>
        public SelectFieldListStatement SelectList { get; set; }

        /// <summary>
        /// From子句
        /// </summary>
        public From From { get; set; }

        /// <summary>
        /// 查询中主表的From语句项。
        /// </summary>
        public FromItem MainFromItem
        {
            get
            {
                return this.mainFromItem;
            }
        }

        /// <summary>
        /// 多表的连接条件
        /// </summary>
        public JoinConditionStatement JoinCondition { get; set; }

        /// <summary>
        /// 过滤条件
        /// </summary>
        public ConditionStatement FilterCondition { get; set; }

        /// <summary>
        /// 排序条件
        /// </summary>
        public ConditionStatement OrderByCondition { get; set; }

        /// <summary>
        /// 表编号
        /// </summary>
        public string TableCode { get; set; }

        /// <summary>
        /// 主键列表
        /// </summary>
        public SqlPrimaryKey PrimaryKeys { get; set; }

        ///// <summary>
        ///// SQL语句构造中用到的中间变量
        ///// </summary>
        //public SqlBuildingInfo SqlBuildingInfo { get; set; }

        /// <summary>
        /// 返回获取数据的前多少条，默认值-1
        /// </summary>
        public int TopSize
        {
            get
            {
                return topSize;
            }
            set
            {
                topSize = value;
            }
        }

        /// <summary>
        /// 如果使用字段别名，那么此属性表示映射后的顺序号
        /// </summary>
        public int AliasCount { get; set; }

        /// <summary>
        /// 字段别名映射
        /// </summary>
        public Dictionary<string,string> DictFieldAliasMapping { get; set; }

        #endregion

        #region 方法

        /// <summary>
        /// 转换成SQL语句
        /// </summary>
        /// <returns>Select SQL语句</returns>
        public override string ToSQL()
        {
            var stringBuilder = new StringBuilder();
            stringBuilder.Append(string.Format("(SELECT {0} FROM {1} ", SelectList.ToSQL(), From.ToSQL()));
            foreach (SqlElement element in MainFromItem.ChildCollection)
            {
                if (element is InnerJoinItem innerJoinItem)
                {
                    if (innerJoinItem.IsExtendItem)
                        stringBuilder.Append(innerJoinItem.ToSQLEx());
                    else
                        stringBuilder.Append(innerJoinItem.ToSQL());
                }
                else if (element is LeftJoinItem leftJoinItem)
                {
                    stringBuilder.Append(leftJoinItem.ToSQL());
                }
            }

            var joinCondition = JoinCondition.ToSQL();
            if (!string.IsNullOrWhiteSpace(joinCondition))
            {
                stringBuilder.AppendFormat("WHERE {0} ", joinCondition);
            }

            var filterCondition = FilterCondition.ToSQL();
            if (!string.IsNullOrWhiteSpace(filterCondition))
            {
                if (string.IsNullOrWhiteSpace(joinCondition))
                {
                    stringBuilder.AppendFormat("WHERE {0} ", filterCondition);
                }
                else
                {
                    stringBuilder.AppendFormat("AND {0} ", filterCondition);
                }
            }
            var orderbyCondition = OrderByCondition.ToSQL();
            if (!string.IsNullOrWhiteSpace(orderbyCondition))
            {
                stringBuilder.AppendFormat("ORDER BY {0}", orderbyCondition);
            }

            stringBuilder.AppendFormat(") {0}", TableAlias);

            return stringBuilder.ToString();
        }

        #endregion
    }
}
